package com.lanyou.cook.upload.service.impl;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import com.lanyou.cook.upload.commons.Constants;
import com.lanyou.cook.upload.dao.impl.TCookBuParamSetDao;
import com.lanyou.cook.upload.entity.TCookBuParamSet;
import com.lanyou.cook.upload.service.UploadFileService;

/**
 * UploadFileService 的实现类
 * 
 * @author ly-lihailang
 *
 */
public class UploadFileServiceImpl implements UploadFileService {
	private TCookBuParamSetDao cookBuParamSetDao;

	@Override
	public TCookBuParamSet getFilePath(String paramName) {

		return cookBuParamSetDao.findByCode(paramName);
	}

	@Override
	public String upLoadFile(HttpServletRequest servletRequest) {

		// 得到上传文件的保存目录
		String proPath = this.getFilePath(Constants.BUNDLE_FILE_UPLOAD_PATH)
				.getParamValue();
		String filePath = proPath + Constants.BUNDLE_FILE_UPLOAD_DIR;
		File file = new File(filePath);
		// 判断上传文件的保存目录是否存在
		if (!file.exists() && !file.isDirectory()) {
			System.out.println(proPath + "目录不存在，需要创建");
			// 创建目录
			file.mkdir();
		}
		// 消息提示
		String message = "";
		try {
			String userName = servletRequest.getParameter("userName");
			String pwd = servletRequest.getParameter("pwd");
			// 使用Apache文件上传组件处理文件上传步骤：
			// 1、创建一个DiskFileItemFactory工厂
			DiskFileItemFactory factory = new DiskFileItemFactory();
			// 2、创建一个文件上传解析器
			ServletFileUpload upload = new ServletFileUpload(factory);
			// 解决上传文件名的中文乱码
			upload.setHeaderEncoding("UTF-8");
			// 3、判断提交上来的数据是否是上传表单的数据
//			if (!ServletFileUpload.isMultipartContent(servletRequest)) {
//				// 按照传统方式获取数据
//				return Constants.BUNDLE_FILE_UPLOAD_IS_NOT_FORM;
//			}
			// 4、使用ServletFileUpload解析器解析上传数据，解析结果返回的是一个List<FileItem>集合，每一个FileItem对应一个Form表单的输入项
			List<FileItem> list = upload.parseRequest(servletRequest);
			if (checkPower(list,userName,pwd)) {// 校验成功则上传
				message = uploadFile(list, filePath);
			} else {
				message = Constants.BUNDLE_FILE_UPLOAD_FAIL;
			}
		} catch (Exception e) {
			message = Constants.BUNDLE_FILE_UPLOAD_FAIL;
			e.printStackTrace();
		}
		return message;
	}

	/**
	 * 校验隐藏域的条件是否符合上传标准
	 * 
	 * @param list
	 *            form表单中的组件列表
	 * @return 校验结果
	 */
	private boolean checkPower(List<FileItem> list,String userName,String pwd) {
		TCookBuParamSet dbUser = null;
//		String pwd = pwd;
		try {
			if(userName==null){
				for (FileItem item : list) {
					// 如果fileitem中封装的是普通输入项的数据
					if (item.isFormField()) {
						String name = item.getFieldName();
						// 解决普通输入项的数据的中文乱码问题
						String value = item.getString("UTF-8");
						// value = new String(value.getBytes("iso8859-1"),"UTF-8");
						if (name.equals(Constants.BUNDLE_FILE_UPLOAD_USERNAME)) {
							// 获取表中对应的用户
							dbUser = this.getFilePath(value);
						} else if (name
								.equals(Constants.BUNDLE_FILE_UPLOAD_PASSWORD)&&pwd==null) {
							// 校验码
							pwd = value;
						}
						System.out.println(name + "=" + value);
					}
				}
			}else{
				dbUser= this.getFilePath(userName);
			}
			
			if (dbUser == null) {// 用户不存在
				return false;
			} else if (!dbUser.getParamValue().equals(pwd)) {// 校验码与用户对应的表中的校验码不一致
				return false;
			}
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	/**
	 * @param list
	 *            form表单中的组件列表
	 * @param filePath
	 *            上传文件保存路径
	 * @return 上传文件的结果
	 */
	private String uploadFile(List<FileItem> list, String filePath) {
		try {
			for (FileItem item : list) {
				if (!item.isFormField()) {
					// 如果fileitem中封装的是上传文件
					// 得到上传的文件名称，
					String filename = item.getName();
					System.out.println(filename);
					if (filename == null || filename.trim().equals("")) {
						continue;
					}
					// 注意：不同的浏览器提交的文件名是不一样的，有些浏览器提交上来的文件名是带有路径的，如：
					// c:\a\b\1.txt，而有些只是单纯的文件名，如：1.txt
					// 处理获取到的上传文件的文件名的路径部分，只保留文件名部分
					filename = filename
							.substring(filename.lastIndexOf("\\") + 1);
					// 获取item中的上传文件的输入流
					InputStream in = item.getInputStream();
					// 创建一个文件输出流
					FileOutputStream out = new FileOutputStream(filePath + "\\"
							+ filename);
					// 创建一个缓冲区
					byte buffer[] = new byte[1024];
					// 判断输入流中的数据是否已经读完的标识
					int len = 0;
					// 循环将输入流读入到缓冲区当中，(len=in.read(buffer))>0就表示in里面还有数据
					while ((len = in.read(buffer)) > 0) {
						// 使用FileOutputStream输出流将缓冲区的数据写入到指定的目录(savePath + "\\"
						// + filename)当中
						out.write(buffer, 0, len);
					}
					// 关闭输入流
					in.close();
					// 关闭输出流
					out.close();
					// 删除处理文件上传时生成的临时文件
					item.delete();
					// message = "文件上传成功！";
				}
			}
			return Constants.BUNDLE_FILE_UPLOAD_SUCCESS;
		} catch (Exception e) {
			return Constants.BUNDLE_FILE_UPLOAD_FAIL;
		}
	}

	public TCookBuParamSetDao getCookBuParamSetDao() {
		return cookBuParamSetDao;
	}

	public void setCookBuParamSetDao(TCookBuParamSetDao cookBuParamSetDao) {
		this.cookBuParamSetDao = cookBuParamSetDao;
	}

}
